import {
  IApplication,
  IFile,
  IForm,
  IPerson,
  ISession,
  ITarget,
  IWork,
  IWorkTask,
  DataProvider,
  IBelong
} from '@/ts/core'
import { common, kernel } from '@/ts/base'
import { IWorkProvider } from '../core/work/provider'
import { IPageTemplate } from '../core/thing/standard/page'
import { IBoxProvider } from '../core/work/box'
import { AuthProvider } from '../core/provider/auth'
import { HomeProvider } from '../core/provider/home'
/** 控制器基类 */
export class Controller extends common.Emitter {
  public currentKey: string
  constructor(key: string) {
    super()
    this.currentKey = key
  }
}
/**
 * 设置控制器
 */
class IndexController extends Controller {
  static _provider: DataProvider
  constructor() {
    super('')
    if (IndexController._provider === undefined) {
      IndexController._provider = new DataProvider(this)
    }
  }
  /** 是否已登录 */
  get logined(): boolean {
    return this.provider.user != undefined
  }
  /** 数据提供者 */
  get provider(): DataProvider {
    if (IndexController._provider === undefined) {
      IndexController._provider = new DataProvider(this)
    }
    return IndexController._provider
  }
  /** 授权方法 */
  get auth(): AuthProvider {
    return this.provider.auth
  }
  /** 当前用户 */
  get user(): IPerson {
    return this.provider.user!
  }
  /** 办事提供者 */
  get work(): IWorkProvider {
    return this.provider.work!
  }
    /** 主页提供者 */
  get home(): HomeProvider {
    return this.provider.home!;
  }
      /** 所有的空间 */
  get spaces(): IBelong[] {
    return this.provider.spaces;
  }
  /** 暂存提供者 */
  get box(): IBoxProvider {
    return this.provider.box!
  }
  /** 所有相关的用户 */
  get targets(): ITarget[] {
    return this.provider.targets
  }
  /** 退出 */
  exit(): void {
    uni.clearStorageSync()
    IndexController._provider = new DataProvider(this)
  }
  async loadApplications(): Promise<IApplication[]> {
    const apps: IApplication[] = []
    for (const directory of this.targets
      .filter(i => i.session.isMyChat)
      .map(a => a.directory)) {
      apps.push(...(await directory.loadAllApplication()))
    }
    return apps
  }
  /** 根据id查找文件 */
  async searchFile(
    targetId: string,
    belongId: string,
    id: string,
    applicationId: string,
    isVirtual?: boolean
  ): Promise<IFile | undefined> {
    let entity
    if (isVirtual) {
      entity = await this.provider.targets
        .find(i => i.id === targetId)
        ?.directory.searchFile(belongId, 'undefined', id, 'id', isVirtual)
    } else {
      const entitys = []
      const applicationIds = applicationId.split('_')
      for (const directory of this.targets.map(a => a.directory)) {
        if (directory.id === belongId) {
          const apps = await directory.loadAllApplication()
          const dirs = await directory.loadAllDirectory()
          const app = apps.find(app => app.id === applicationIds[0])
          const dir = dirs.find(dir => dir.id === applicationIds[0])
          if (app) {
            entitys.push(app)
            entitys.push(...(await app.loadAllWorks()))
            entitys.push(...(await app.loadAllForms()))
          }
          if (dir) {
            entitys.push(dir)
            entitys.push(...dir.standard.forms)
            entitys.push(...dir.standard.directorys)
            entitys.push(...dir.standard.applications)
          }
        }
      }
      entity = entitys.find(item => item!.id === id)
      if (!entity) {
        entity = await this.provider.targets
          .find(i => i.id === targetId)
          ?.directory.searchFile(belongId, applicationIds[0], id)
      }
    }
    return entity
  }
  /** 根据id查找办事 */
  async searchWork(
    belongId: string,
    id: string
  ): Promise<IWork | IWorkTask | undefined> {
    for (const directory of this.targets.map(a => a.directory)) {
      if (directory.id === belongId) {
        const apps = await directory.loadAllApplication()
        for (const app of apps) {
          const works = await app.loadAllWorks()
          const work = works.find(work => work.id === id)
          if (work) {
            return work
          }
        }
      }
    }
    return undefined
  }
  /** 根据id查找表单 */
  async searchForm(
    shareId: string,
    directoryId: string,
    applicationId: string,
    id: string
  ): Promise<IForm | undefined> {
    for (const directory of this.targets.map(a => a.directory)) {
      if (directory.id === shareId) {
        const form = await directory.searchFile(directoryId, applicationId, id)
        console.log(directory, form)
        return form as IForm
      }
    }
    return undefined
  }
  /** 加载所有常用 */
  async loadCommons(): Promise<IFile[]> {
    const files: IFile[] = []
    if (this.provider.user) {
      for (const item of this.provider.user.commons) {
        const target = this.provider.targets.find(
          i => i.id === item.targetId && i.spaceId === item.spaceId
        )
        if (target) {
          const file = await target.directory.searchFile(
            item.directoryId,
            item.applicationId,
            item.id
          )
          if (file) {
            files.push(file)
          }
        }
      }
    }
    return files
  }
  /** 所有相关会话 */
  get chats(): ISession[] {
    const chats: ISession[] = []
    if (this.provider.user) {
      chats.push(...this.provider.user.chats)
      for (const company of this.provider.user.companys) {
        chats.push(...company.chats)
      }
    }
    return chats
  }
  /** 所有相关页面 */
  async loadPages(): Promise<IPageTemplate[]> {
    const pages: IPageTemplate[] = []
    for (const directory of this.targets.map(t => t.directory)) {
      const templates = await directory.loadAllTemplate()
      pages.push(...templates.filter(item => item.metadata.public))
    }
    return pages
  }

  /** 加入申请 */
  async joinTarget(targetId: string) {
    const entity = await this.user.findEntityAsync(targetId)

    if (null == entity) {
      uni.showToast({
        title: '获取对象失败',
        icon: 'none',
        duration: 2000
      })
      return
    }

    const target = await this.user.searchTargets(entity.code!, [
      entity.typeName!
    ])

    if (target.length != 0) {
      var success = await this.user.applyJoin(target)
      if (success) {
        uni.showToast({
          title: '申请发送成功，请等待审批~',
          icon: 'success',
          duration: 2000
        })
      } else {
        uni.showToast({
          title: '您已发起申请或已加入,请勿重复申请',
          icon: 'none',
          duration: 2000
        })
      }
    } else {
      uni.showToast({
        title: '获取对象失败',
        icon: 'none',
        duration: 2000
      })
    }
  }

  /** 扫码加载表单数据 */
  async loadFormByQRCode(
    key: string,
    password?: string,
    resourceId?: string,
    loadOptions?: object
  ) {
    return await kernel.loadShare({
      key,
      password,
      resourceId,
      loadOptions
    })
  }
}

export default new IndexController()
